#coding:utf-8
import time

import grpc
import hello_bibi_pb2 as pb2
import hello_bibi_pb2_grpc as pb2_grpc
from concurrent import futures
#书写拦截器类
def _abort(code,details):
    def terminate(ignored_request,context):
        context.abort(code,details)
    return grpc.unary_unary_rpc_method_handler(terminate)
class TestInterceptor(grpc.ServerInterceptor):
    def __init__(self,key,value,code,detail):
        self.key=key
        self.value=value
        self._abort=_abort(code,detail)
    def intercept_service(self, continuation, handler_call_details):
        headers=dict(handler_call_details.invocation_metadata)


        if headers.get(self.key,'')!=self.value:
            return self._abort
        if (self.key,self.value) not in handler_call_details.invocation_metadata:
            return self._abort
        return continuation(handler_call_details)

class Bibili(pb2_grpc.BibiliServicer):
    def HelloDewei(self,request,context):
        name=request.name
        age=request.age

        # context.set_details('haha bug')
        # context.set_code(grpc.StatusCode.DATA_LOSS)
        # raise context
        context.set_trailing_metadata((('name','dewei'),('key','value')))
        headers=context.invocation_metadata()
        print(headers[0].key,headers[0].value)
        result=f"my name is {name},i am {age} years old"
        context.set_compression(grpc.Compression.Gzip)#
        return pb2.HelloDeweiReply(result=result)
    def TestClientRecvStream(self,request,context):
         index=0
         while context.is_active():
             data=request.data
             if data=='close':
                 context.cancel()
             time.sleep(1)
             index+=1
             yield pb2.TestClientRecvStreamResponse(
                 result='send %d %s'% (index,data)
             )
    def TestClientSendStream(self, request_iterator, context):
        index=0
        for request_iterator in request_iterator:
            print(request_iterator.data,':',index)
            if index==10:
                break
            index+=1

        return pb2.TestClientSendStreamResponse(result='OK')
    def TestTwoWayStream(self, request_iterator, context):
        for request in request_iterator:
            print(request)
            data=request.data

            yield  pb2.TestTwoWayStreamResponse(result='service send client %s'%data)

def run():
    validator=TestInterceptor('name','dewei',grpc.StatusCode.UNIMPLEMENTED,'Access denined')
    grpc_server=grpc.server(
        futures.ThreadPoolExecutor(max_workers=4),
        compression=grpc.Compression.Gzip,
        interceptors=(validator,),
        options=[
            ('grpc.max_send_message_length',50*1024*1024),
            ('grpc.max_receive_message_length',50*1024*1024)
        ]
    )
    pb2_grpc.add_BibiliServicer_to_server(Bibili(),grpc_server)
    grpc_server.add_insecure_port('127.0.0.1:5000')
    print('server will start at 127.0.0.1:5000')
    grpc_server.start()
    try:
        while 1:
            time.sleep(3600)
    except KeyboardInterrupt:
        grpc_server.stop(0)
if __name__=='__main__':
    run()